package com.java.st.lib.tools.mapper;

import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.BeanUtilsBean;
import org.dozer.DozerBeanMapper;
import org.dozer.Mapper;

import com.java.st.lib.tools.collection.ArrayUtil;
import com.java.st.lib.tools.collection.ListUtil;

/**
 * 实现深度的BeanOfClasssA<->BeanOfClassB复制
 * 
 * Dozer最新是6.x版，但only for JDK8，为兼容JDK7这里仍使用5.x版本。
 * 
 * 注意: 需要参考POM文件，显式引用Dozer.
 */
public class BeanMapper extends BeanUtils {

	private static Mapper mapper = new DozerBeanMapper();

	/**
	 * 简单的复制出新类型对象.
	 */
	public static <S, D> D map(S source, Class<D> destinationClass) {
		return mapper.map(source, destinationClass);
	}

	/**
	 * 简单的复制出新对象ArrayList
	 */
	public static <S, D> List<D> mapList(Iterable<S> sourceList, Class<D> destinationClass) {
		List<D> destionationList = new ArrayList<D>();
		for (S source : sourceList) {
			if (source != null) {
				destionationList.add(mapper.map(source, destinationClass));
			}
		}
		return destionationList;
	}

	/**
	 * 简单复制出新对象数组
	 */
	public static <S, D> D[] mapArray(final S[] sourceArray, final Class<D> destinationClass) {
		D[] destinationArray = ArrayUtil.newArray(destinationClass, sourceArray.length);

		int i = 0;
		for (S source : sourceArray) {
			if (source != null) {
				destinationArray[i] = mapper.map(sourceArray[i], destinationClass);
				i++;
			}
		}

		return destinationArray;
	}

	/**
	 * 同一个类的对象之间的非空属性拷贝
	 * 
	 */
	public static void copyNotNull(Object source, Object target) {
		final PropertyDescriptor[] origDescriptors = BeanUtilsBean.getInstance().getPropertyUtils()
				.getPropertyDescriptors(source);
		for (PropertyDescriptor origDescriptor : origDescriptors) {
			final String name = origDescriptor.getName();
			if ("class".equals(name)) {
				continue;
			}
			if (BeanUtilsBean.getInstance().getPropertyUtils().isReadable(source, name)
					&& BeanUtilsBean.getInstance().getPropertyUtils().isWriteable(target, name)) {
				try {
					final Object value = BeanUtilsBean.getInstance().getPropertyUtils().getSimpleProperty(source, name);
					if (value != null) {
						copyProperty(target, name, value);
					}
				} catch (Exception e) {
					// Should not happen
				}
			}
		}
	}

	/**
	 * 两个List之间的对象非空属性拷贝 目标List的Size>=源List的Size
	 */
	public static void copyNotNullList(List<?> sourceList, List<?> targetList) throws Exception {
		if (ListUtil.isNotEmpty(sourceList) && ListUtil.isNotEmpty(targetList)
				&& targetList.size() >= sourceList.size()) {
			int index = 0;
			for (Object object : sourceList) {
				copyNotNull(object, targetList.get(index++));
			}
		}
	}
}